#include "formatinfo.h"
#include "common/symbol.h"
#include "common/bch.h"
#include "common/stringutils.h"

#include <QDebug>

namespace qrcode {


FormatInfo::FormatInfo()
{
    maskBits15_5 = {1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0};
}

void FormatInfo::Creator()
{
    //1.格式信息
    std::vector<int> format = GetInitFormatInfo();
    StringUtils::PRINT("格式信息: ", format);

    StringUtils::PRINT("纠错等级：", errorlevel);
    StringUtils::PRINT("掩模模式：", masknum);

    //2.计算纠错码
    BCH *qbch = new BCH();
    std::vector<int> ecc = qbch->Encoding15_5(format);

    //3.将格式信息与纠错码连接
    ConnectBits(format, ecc);

    StringUtils::PRINT("原格式信息数据位流：", format);

    //4.与掩模数据串异或
    XOR(format, maskBits15_5);

    StringUtils::PRINT("掩模后的格式信息数据位流：", format);

    formatbitstream = format;
}

void FormatInfo::RemoveMask(std::vector<int> &vec)
{
    XOR(vec, maskBits15_5);
}

std::vector<int> FormatInfo::GetInitFormatInfo()
{
    std::vector<int> vec1 = GetLevelNum(errorlevel);
    std::vector<int> vec2 = GetMaskNum(masknum);

    std::vector<int> vec;

    for(int i = 0; i < vec1.size(); i++){
        vec.push_back(vec1.at(i));
    }
    for(int i = 0; i < vec2.size(); i++){
        vec.push_back(vec2.at(i));
    }
    return vec;
}

std::vector<int> FormatInfo::GetLevelNum(char &errorlevel)
{
    std::vector<int> vec;

    switch (errorlevel) {
    case ERROR_CORRECTION_LEVEL_L:
        vec.push_back(0);
        vec.push_back(1);
        break;
    case ERROR_CORRECTION_LEVEL_M:
        vec.push_back(0);
        vec.push_back(0);
        break;
    case ERROR_CORRECTION_LEVEL_Q:
        vec.push_back(1);
        vec.push_back(1);
        break;
    case ERROR_CORRECTION_LEVEL_H:
        vec.push_back(1);
        vec.push_back(0);
        break;
    default:
        break;
    }
    return vec;
}

std::vector<int> FormatInfo::GetMaskNum(int &masknum)
{
    std::vector<int> vec;

    switch (masknum) {
    case 0:
        vec.push_back(0);
        vec.push_back(0);
        vec.push_back(0);
        break;
    case 1:
        vec.push_back(0);
        vec.push_back(0);
        vec.push_back(1);
        break;
    case 2:
        vec.push_back(0);
        vec.push_back(1);
        vec.push_back(0);
        break;
    case 3:
        vec.push_back(0);
        vec.push_back(1);
        vec.push_back(1);
        break;
    case 4:
        vec.push_back(1);
        vec.push_back(0);
        vec.push_back(0);
        break;
    case 5:
        vec.push_back(1);
        vec.push_back(0);
        vec.push_back(1);
        break;
    case 6:
        vec.push_back(1);
        vec.push_back(1);
        vec.push_back(0);
        break;
    case 7:
        vec.push_back(1);
        vec.push_back(1);
        vec.push_back(1);
        break;
    default:
        break;
    }
    return vec;
}

void FormatInfo::ConnectBits(std::vector<int> &vec, std::vector<int> &vec1)
{
    for(int i = 0; i < vec1.size(); i++){
        vec.push_back(vec1.at(i));
    }
}

void FormatInfo::XOR(std::vector<int> &vec, std::vector<int> &vec1)
{
    std::vector<int> v;
    for(int i = 0; i < vec.size(); i++){
        v.push_back(vec.at(i)^vec1.at(i));
    }
    vec = v;
}
void FormatInfo::setErrorlevel(char value)
{
    errorlevel = value;
}

void FormatInfo::setMasknum(int value)
{
    masknum = value;
}

std::vector<int> FormatInfo::getFormatbitstream() const
{
    return formatbitstream;
}


}
